/**   
 * @Title: RebuildTicketServiceImpl
 * @Package com.isoftstone.industry.aaa.core.service.rebuildticket.impl
 * @Description: TODO
 * @Author Alvin
 * @Date Jun 26, 2014 10:17:44 AM
 * @version V1.0
 */
package com.isoftstone.industry.aaa.core.service.rebuildticket.impl;

import java.sql.Timestamp;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.isoftstone.industry.common.util.CommonUtils;
import com.isoftstone.industry.common.util.DateUtils;
import com.isoftstone.industry.common.util.SNGenerator;
import com.isoftstone.industry.persistance.bean.AppInstMemberRls;
import com.isoftstone.industry.persistance.bean.AppInstance;
import com.isoftstone.industry.persistance.bean.BillingUserOverview;
import com.isoftstone.industry.persistance.bean.ProductInstance;
import com.isoftstone.industry.persistance.bean.TicketInfo;
import com.isoftstone.industry.persistance.bean.TicketRebuildLog;
import com.isoftstone.industry.persistance.bean.TicketRebuildTask;
import com.isoftstone.industry.aaa.core.dao.assist.AppInstMemberRlsDao;
import com.isoftstone.industry.aaa.core.dao.assist.AppInstanceDao;
import com.isoftstone.industry.aaa.core.dao.assist.BillingUserOverviewDao;
import com.isoftstone.industry.aaa.core.dao.assist.RebuildTicketDao;
import com.isoftstone.industry.aaa.core.dao.assist.TicketInfoDao;
import com.isoftstone.industry.aaa.core.dao.assist.TicketRebuildLogDao;
import com.isoftstone.industry.aaa.core.service.rebuildticket.IRebuildTicketService;

/**
 * @ClassName: RebuildTicketServiceImpl
 * @Description: TODO
 * @Author Alvin
 * @Date Jun 26, 2014 10:17:44 AM
 */
@Service
public class RebuildTicketServiceImpl implements IRebuildTicketService {
	@Resource
	private RebuildTicketDao rebulidTicketDao;
	@Resource
	private AppInstanceDao appInstanceDao;
	@Resource
	private BillingUserOverviewDao billingUserOverviewDao;
	@Resource
	private TicketInfoDao ticketInfoDao;
	@Resource
	private AppInstMemberRlsDao appInstMemberRlsDao;
	@Resource
	private TicketRebuildLogDao ticketRebuildLogDao;
	/**
	 * @Title: rebuildTicket
	 * @Description: TODO
	 */
	@Override
	@Transactional(rollbackFor={Exception.class})
	public void rebuildTicket() {
		int page = 0; 
        int pageSize = 20; 
        Pageable pageRequest =new PageRequest(page, pageSize); 
		List<TicketRebuildTask> list = rebulidTicketDao.getTicketRebuildTaskList(new Date(), pageRequest);
		for (Iterator<TicketRebuildTask> iterator = list.iterator(); iterator.hasNext();) {
			TicketRebuildTask ticketRebuildTask = iterator.next();
			TicketRebuildLog ticketRebuildLog = new TicketRebuildLog();
			ticketRebuildLog.setTask(ticketRebuildTask);
			try {
				ticketRebuildTask.setRunning(true);
				
				createInitTicketInfo(ticketRebuildTask);
				
				String rebuildType = ticketRebuildTask.getRebuildType();
				Timestamp nextRebuildTime = null;
				if(TicketRebuildTask.RebuildType.MONTH_BASED.equals(rebuildType)){
					nextRebuildTime = DateUtils.dateToTimeStamp(DateUtils.getNextMonthStart(ticketRebuildTask.getNextRebuildTime()), DateUtils.YYYY_MM_DD_HH_MM_SS_PATTERN);
				}else if(TicketRebuildTask.RebuildType.YEAR_BASED.equals(rebuildType)){
					nextRebuildTime = DateUtils.createStartTime(DateUtils.addYear(ticketRebuildTask.getNextRebuildTime(), 1));
				}
				ticketRebuildTask.setNextRebuildTime(nextRebuildTime);
				ticketRebuildTask.setRunning(false);
				
				rebulidTicketDao.update(ticketRebuildTask);
				
				ticketRebuildLog.setResult(TicketRebuildLog.Result.SUCCESS);
				
			} catch (RuntimeException e) {
				ticketRebuildLog.setResult(TicketRebuildLog.Result.FAILED);
			}
			
			ticketRebuildLog.setCreatedTime(DateUtils.getCurrentTimestamp());
			ticketRebuildLogDao.save(ticketRebuildLog);
		}
	}
	
	/**
	  * @Title: initTicketInfo
	  * @Description: 生成相应的初始化话单信息
	  * @param appInstId
	  * @Return void
	 */
	private void createInitTicketInfo(TicketRebuildTask ticketRebuildTask){
		
		String appInstId = ticketRebuildTask.getAppInst().getId();
		AppInstance appInstance = appInstanceDao.findOne(appInstId);
		ProductInstance productInstance = appInstance.getProdInst();
		Timestamp now = DateUtils.getCurrentTimestamp();
		
		//BillingUserOverview的BillingUserNum变更为LicensedUserNum
		BillingUserOverview billingUserOverview;
		if (CommonUtils.isEmpty(productInstance.getPackProdInst())) {
			billingUserOverview = billingUserOverviewDao.getBillingUserOverviewByAppInstId(appInstId);
		}else{
			billingUserOverview = billingUserOverviewDao.getBillingUserOverviewByAppProdId(productInstance.getPackProdInst().getId());
		}
		
		//备份历史数据
		BillingUserOverview billingUserOverviewHist = new BillingUserOverview();
		billingUserOverviewHist.setLicensedUserNum(billingUserOverview.getLicensedUserNum());
		billingUserOverviewHist.setBillingUserNum(billingUserOverview.getBillingUserNum());
		billingUserOverviewHist.setFreeUserNum(billingUserOverview.getFreeUserNum());
		billingUserOverviewHist.setAppInstance(billingUserOverview.getAppInstance());
		billingUserOverviewHist.setUser(billingUserOverview.getUser());
		billingUserOverviewHist.setUpdatedTime(now);
		billingUserOverviewHist.setIsHistroy(true);
		Date beginDate = null;
		Date endDate = DateUtils.getDateChangeTime(ticketRebuildTask.getNextRebuildTime(), "s", -1);
		String rebuildType = ticketRebuildTask.getRebuildType();
		if(rebuildType.equals(TicketRebuildTask.RebuildType.MONTH_BASED)){
			beginDate = DateUtils.convertToFirstDay(endDate);
			billingUserOverviewHist.setStatisticType(BillingUserOverview.StatisticType.MONTH_BASED);
		}else if(rebuildType.equals(TicketRebuildTask.RebuildType.YEAR_BASED)){
			beginDate = DateUtils.getDateChangeTime(ticketRebuildTask.getNextRebuildTime(), "y", -1);
			billingUserOverviewHist.setStatisticType(BillingUserOverview.StatisticType.YEAR_BASED);
		}
		billingUserOverviewHist.setBeginDate(beginDate);
		billingUserOverviewHist.setEndDate(endDate);
		billingUserOverviewDao.save(billingUserOverviewHist);
		
		billingUserOverview.setBillingUserNum(billingUserOverview.getLicensedUserNum());
		billingUserOverview.setUpdatedTime(now);
		billingUserOverviewDao.update(billingUserOverview);
		
		//生成本计费周期的初始话单信息
		List<AppInstMemberRls> list = appInstMemberRlsDao.getAppInstMemberRlsList(appInstId);
		int overUserNum = billingUserOverview.getBillingUserNum() - billingUserOverview.getFreeUserNum();
		if (CommonUtils.isNotEmpty(list) && overUserNum > 0) {
			TicketInfo ticketInfo = null;
			long userOrder = 0;
			for (Iterator<AppInstMemberRls> iterator = list.iterator(); iterator.hasNext();) {
				AppInstMemberRls appInstMemberRls = iterator.next();
				
				ticketInfo = new TicketInfo();
				ticketInfo.setSn(SNGenerator.createTiketInfoSn());
				ticketInfo.setAppInstance(appInstance);
				ticketInfo.setUser(appInstance.getProdInst().getUser());
				ticketInfo.setMember(appInstMemberRls.getUser());
				ticketInfo.setChargeMode(TicketInfo.IChargeMode.USER_BASED);
				ticketInfo.setOrignFlag(TicketInfo.IOrginFlag.CLOUD_PLATFORM);
				ticketInfo.setCreatedTime(DateUtils.getCurrentTimestamp());
				ticketInfo.setCharged(false);
				ticketInfo.setChargeOrder(++userOrder);
				ticketInfoDao.save(ticketInfo);
				if(userOrder == overUserNum){
					break;
				}
			}
		}
			
	}

}
